package com.feihong.txgw.utils.sign;

import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.EncodeUtils;
import com.blankj.utilcode.util.EncryptUtils;
import com.feihong.txgw.app.App;
import com.feihong.txgw.global.GlobalContents;
import com.feihong.txgw.utils.PreferenceTools;
import com.feihong.txgw.utils.UserLoginInfo;

import java.security.Key;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import okhttp3.Request;

/**
 * @Author wangziheng
 * @ProjectName txgw_app
 * @ClassName SignToken
 * @package com.feihong.txgw.utils.sign
 * @data 2018/5/2 18:38
 * @Describe
 * @Change
 */
public class SignToken {

    /**
     * 密钥
     */
    private static final String SIGEN = "ca43567f18f93d7f8b6631a56fab04eb";

    private final static String secretKey = "Tong1TCssa77XunGu00aqxD2";
    /**
     * 向量
     */
    private final static String iv = "01234567";
    /**
     * 加解密统一使用的编码方式
     */
    private final static String encoding = "utf-8";

    public final static String sToken = "token";
    public final static String sVersion = "version";
    public final static String sData = "data";
    public final static String sSign = "sign";

    public Map<String, String> setSigen(Map requestParams) {
        Map<String, String> Outparams = new HashMap<>();


        String token = UserLoginInfo.getUserToken();
//        String token = "46ae3299930a85dd080bb58972d6120b";
        if (!TextUtils.isEmpty(token)) {
            Outparams.put("token", token);
        }
        //推送的ID
        String identify = PreferenceTools.getString(GlobalContents.REGID, UUID.randomUUID().toString());

        Outparams.put("version", AppUtils.getAppVersionName());
        // 手机唯一标识
        requestParams.put("identify", identify);
        requestParams.put("version", AppUtils.getAppVersionName());
        //请求形式Post
        requestParams.put("reqtype", "post");
        requestParams.put("timestamp", System.currentTimeMillis() / 1000 + "");
        if (UserLoginInfo.isUserLogin()) {
            requestParams.put("mobile", UserLoginInfo.getUserPhone());
            requestParams.put("user_id", UserLoginInfo.getUserId());
        }

        Map<String, String> map = new TreeMap<String, String>(
                new Comparator<String>() {
                    @Override
                    public int compare(String obj1, String obj2) {
                        // 升序排序
                        return obj1.compareTo(obj2);
                    }
                });
        String data = JSON.toJSONString(requestParams);
        Log.i("请求参数：加密前的", "setSigen: "+data);
        try {
            data = encrypt(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = new String(EncodeUtils.base64Encode(data));
        map.put("version", AppUtils.getAppVersionName());
        Outparams.put("data", data);
        map.put("data", data);
        if (!TextUtils.isEmpty(token)) {
            map.put("token", token);
        }

        Set<String> set = map.keySet();
        StringBuffer sb = new StringBuffer();
        int num = 0;
        for (Iterator<String> iter = set.iterator(); iter.hasNext(); ) {
            String key = iter.next();
            sb.append(key + "=" + map.get(key));

            if (num < set.size() - 1) {
                sb.append("&");
            }
            num += 1;
        }
        String handled_str = sb.toString().trim();
        String sign = EncryptUtils.encryptMD5ToString(handled_str + "|||" + SIGEN);
        Outparams.put("sign", sign.toLowerCase());
        return Outparams;
    }

    public String setSigen(HashMap<String, String> requestParams) {
        Map<String,String> newParams;
        newParams = setGetSign(requestParams);
        //生成URL get参数
        StringBuffer sb = new StringBuffer();
        Iterator<Map.Entry<String, String>> newitems = newParams.entrySet().iterator();
        int index = 0;
        int lastIndex = newParams.size() - 1;
        while (newitems.hasNext()) {
            Map.Entry<String, String> item = newitems.next();
            sb.append(item.getKey() + "=" + item.getValue());
            if (index < lastIndex) {
                sb.append("&");
            }
            index++;
        }
        return sb.toString();
    }

    public Map<String,String> setGetSign(Map<String, String> requestParams){
        HashMap<String, String> params = new HashMap<>();
        String token = UserLoginInfo.getUserToken();
        Iterator<Map.Entry<String, String>> items = requestParams.entrySet().iterator();
        StringBuffer stringBuffer = new StringBuffer();
        while (items.hasNext()) {
            Map.Entry<String, String> item = items.next();
            params.put(item.getKey(), item.getValue());
            stringBuffer.append(item.getKey()+":"+item.getValue());
        }
        requestParams.clear();
        requestParams = new HashMap<>();
        requestParams.put("token", token);
        requestParams.put("version", AppUtils.getAppVersionName());
        //推送的ID
        String identify = PreferenceTools.getString(GlobalContents.REGID, UUID.randomUUID().toString());
        // 手机唯一标识
        params.put("identify", identify);
        params.put("version", AppUtils.getAppVersionName());
        params.put("reqtype","get");
        if (UserLoginInfo.isUserLogin()) {
            params.put("mobile", UserLoginInfo.getUserPhone());
            params.put("user_id", UserLoginInfo.getUserId());
        }
        params.put("timestamp", System.currentTimeMillis() / 1000 + "");
        Map<String, String> map = new TreeMap<String, String>(
                new Comparator<String>() {
                    @Override
                    public int compare(String obj1, String obj2) {
                        // 升序排序
                        return obj1.compareTo(obj2);
                    }
                });
        String data = JSON.toJSONString(params);
        Log.i("请求参数：加密前的", "setGetSign: "+params);
        try {
            data = encrypt(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = new String(EncodeUtils.base64Encode(data));
        map.put("version", AppUtils.getAppVersionName());
        requestParams.put("data", data);
        map.put("data", data);
        map.put("token", token);

        Set<String> set = map.keySet();
        StringBuffer sb = new StringBuffer();
        int num = 0;
        for (Iterator<String> iter = set.iterator(); iter.hasNext(); ) {
            String key = iter.next();
            sb.append(key + "=" + map.get(key));

            if (num < set.size() - 1) {
                sb.append("&");
            }
            num += 1;
        }
        String handled_str = sb.toString().trim();
        String sign = EncryptUtils.encryptMD5ToString(handled_str + "|||" + SIGEN);
        requestParams.put("sign", sign.toLowerCase());
        return requestParams;
    }
    private String encrypt(String plainText) throws Exception {
        Key deskey = null;
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes("UTF-8"));
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        deskey = keyfactory.generateSecret(spec);

        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
        return Base64.encodeToString(encryptData, Base64.DEFAULT);
    }

    /**
     * 此次请求是否需要加密
     */
    public static boolean isNeedSignPath(Request request){
        String path = request.url().encodedPath();
        return !App.getApp().mSpecialPath.contains(path);
    }
}
